package com.rp.system.user.filter;//package com.rp.system.user.filter;
//
///**
// * 类说明:
// *
// * @author ****
// * @date 2020-12-21 17:09  新建
// */
//
//import com.alibaba.druid.util.PatternMatcher;
//import com.alibaba.druid.util.ServletPathMatcher;
//import IPUtils;
//import RedisUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.shiro.web.util.WebUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.context.ApplicationContext;
//import org.springframework.core.annotation.Order;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.data.redis.core.StringRedisTemplate;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.support.WebApplicationContextUtils;
//
//import javax.servlet.*;
//import javax.servlet.annotation.WebFilter;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import javax.servlet.http.HttpServletResponseWrapper;
//import java.io.IOException;
//import java.util.Arrays;
//import java.util.HashSet;
//import java.util.Iterator;
//import java.util.Set;
//import java.util.concurrent.TimeUnit;
//
///**
// * <br>类 名: TokenFilter
// * <br>描 述: TODO
// * <br>作 者: lipeng
// * <br>创 建： 2018/9/29 17:32
// * <br>版 本：v1.0.0
// * <br>
// * <br>历 史: (版本) 作者 时间 注释
// */
//@Slf4j
//@Component
//public class TokenFilter implements Filter {
//
//    //单位时间内最大访问数
//    private static final Integer MAX_COUNT = 15;
//    //单位时间
//    //一秒钟内访问15次
//    private static final Long UNIT_TIME = 10 * 1000L;
//    //限制时长
//    private static final Long REJECT_TIME = 10 * 60 * 1000L;
//
//    @Autowired
//    private RedisUtil redisUtil;
//
//    private ApplicationContext context;
//
//    public static final String PARAM_NAME_EXCLUSIONS = "exclusions";
//    private Set<String> excludesPattern;
//    protected String contextPath;
//    protected PatternMatcher pathMatcher = new ServletPathMatcher();
//
//    public String getContextPath() {
//        return contextPath;
//    }
//
//    public void setContextPath(String contextPath) {
//        this.contextPath = contextPath;
//    }
//
//    @Override
//    public void init(FilterConfig filterConfig) throws ServletException {
//        String param = filterConfig.getInitParameter(PARAM_NAME_EXCLUSIONS);
//        System.out.println(param);
//        if (param != null && param.trim().length() != 0) {
//            this.excludesPattern = new HashSet(Arrays.asList(param.split("\\s*,\\s*")));
//        }
//        context = WebApplicationContextUtils.getWebApplicationContext(filterConfig.getServletContext());
//        if (redisUtil == null) {
//            redisUtil = new RedisUtil();
//            RedisTemplate redisTemplate = (RedisTemplate) context.getBean("redisTemplate");
//            redisUtil.setRedisTemplate(redisTemplate);
//        }
//
//    }
//
//    @Override
//    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
//        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
//        TokenFilter.StatHttpServletResponseWrapper responseWrapper = new TokenFilter.StatHttpServletResponseWrapper(httpResponse);
//        String requestURI = this.getRequestURI(httpRequest);
//        if (this.isExclusion(requestURI)) {
//            //不过滤走
//            System.out.println("===不进过滤器");
//            filterChain.doFilter(servletRequest, servletResponse);
//        } else {
//            //这里是过滤方法
//            System.out.println("===进了过滤器");
//            String ip = IPUtils.getIpAddr(httpRequest);
//            System.out.println("ip: " + ip);
//            boolean boo = true;
//            //过滤黑名单
//            if (redisUtil.hasKey("filter:ip:black:" + ip)) {
//                log.error("ip访问过于频繁，已被限制=>" + ip + " 倒计时" + redisUtil.getExpire("filter:ip:black:" + ip));
//                boo = false;
//            }
//            //判断ip是否首次访问
//            if (redisUtil.hHasKey("filter:ip:normal", "count:" + ip)) {
//                //判断最大访问次数
//                Integer maxCount = Integer.valueOf(redisUtil.hget("filter:ip:normal", "count:" + ip).toString());
//                log.info("ip：" + ip + " 访问" + maxCount + "次");
//                if (maxCount > MAX_COUNT) {
//                    Long maxTime = Long.valueOf(redisUtil.hget("filter:ip:normal", "time:" + ip).toString());
//                    System.out.println(System.currentTimeMillis());
//                    System.out.println(maxTime);
//                    System.out.println((System.currentTimeMillis() - maxTime) / 1000);
//                    if (System.currentTimeMillis() - maxTime < UNIT_TIME) {
//                        log.error("ip访问过于频繁，已被限制=>" + ip + " 倒计时" + REJECT_TIME);
//                        redisUtil.setEx("filter:ip:black:" + ip, "1", REJECT_TIME, TimeUnit.MILLISECONDS);
//                        String str[] = {"count:" + ip, "time:" + ip};
//                        redisUtil.hdel("filter:ip:normal", str);
//                        boo = false;
//                    }
//                    initVisitsIP(ip);
//                }
//            } else {
//                initVisitsIP(ip);
//            }
//            redisUtil.hincr("filter:ip:normal", "count:" + ip, 1);
//            System.out.println(boo);
//            if (boo) {
//                filterChain.doFilter(servletRequest, servletResponse);
//            }else{
//                WebUtils.issueRedirect(servletRequest, servletResponse, "/redirect/accessRestricted?time=" + redisUtil.getExpire("filter:ip:black:" + ip));
//            }
//        }
//    }
//
//    @Override
//    public void destroy() {
//
//    }
//
//    /**
//     * 初始化访问ip
//     *
//     * @param ip
//     */
//    private void initVisitsIP(String ip) {
//        redisUtil.hset("filter:ip:normal", "count:" + ip, 0);
//        redisUtil.hset("filter:ip:normal", "time:" + ip, String.valueOf(System.currentTimeMillis()));
//    }
//
//    public boolean isExclusion(String requestURI) {
//        if (this.excludesPattern == null) {
//            return false;
//        } else {
//            if (this.contextPath != null && requestURI.startsWith(this.contextPath)) {
//                requestURI = requestURI.substring(this.contextPath.length());
//                if (!requestURI.startsWith("/")) {
//                    requestURI = "/" + requestURI;
//                }
//            }
//
//            Iterator i$ = this.excludesPattern.iterator();
//
//            String pattern;
//            do {
//                if (!i$.hasNext()) {
//                    return false;
//                }
//
//                pattern = (String) i$.next();
//            } while (!this.pathMatcher.matches(pattern, requestURI));
//
//            return true;
//        }
//    }
//
//    public static final class StatHttpServletResponseWrapper extends HttpServletResponseWrapper implements HttpServletResponse {
//        private int status = 200;
//
//        public StatHttpServletResponseWrapper(HttpServletResponse response) {
//            super(response);
//        }
//
//        @Override
//        public void setStatus(int statusCode) {
//            super.setStatus(statusCode);
//            this.status = statusCode;
//        }
//
//        @Override
//        public void setStatus(int statusCode, String statusMessage) {
//            super.setStatus(statusCode, statusMessage);
//            this.status = statusCode;
//        }
//
//        @Override
//        public void sendError(int statusCode, String statusMessage) throws IOException {
//            super.sendError(statusCode, statusMessage);
//            this.status = statusCode;
//        }
//
//        @Override
//        public void sendError(int statusCode) throws IOException {
//            super.sendError(statusCode);
//            this.status = statusCode;
//        }
//
//        @Override
//        public int getStatus() {
//            return this.status;
//        }
//    }
//
//    public String getRequestURI(HttpServletRequest request) {
//        return request.getRequestURI();
//    }
//}
//
//
